package pl.edu.pw.ee.buildcity.ui.web.jsf.beans;

import org.apache.log4j.Logger;
import pl.edu.pw.ee.buildcity.entities.BuildDefinition;
import pl.edu.pw.ee.buildcity.scheduler.BuildCityJobDetail;
import pl.edu.pw.ee.buildcity.scheduler.api.BuildCityScheduler;
import pl.edu.pw.ee.buildcity.services.BuildDefinitionService;

import javax.annotation.PostConstruct;
import javax.faces.model.SelectItem;
import java.util.ArrayList;
import java.util.List;

/**
 * @author mgrzechocinski
 * @since 2009-11-08
 */
public class BuildDefinitionsManagerJSFBean {

	private static final Logger log = Logger.getLogger(BuildDefinitionsManagerJSFBean.class);

	private List<SelectItem> availableDefinitions;

	private BuildDefinitionService buildDefinitionService;
	private BuildCityScheduler scheduler;

	private BuildDefinition chosenDefinition;

	private boolean editMode = false;

	@PostConstruct
	private void initBuildDefinitions() {
		try {
			List<BuildDefinition> registeredBuildDefinitions = buildDefinitionService.getAll();
			log.info("Found " + registeredBuildDefinitions.size() + " registered build definitions...");
			fillListOfAvailableDefinitions(registeredBuildDefinitions);
			if (!availableDefinitions.isEmpty()) {
				//Is someone has not set any other... (ie. when clicked in dashboard)
				if (chosenDefinition == null) {
					chosenDefinition = (BuildDefinition) availableDefinitions.get(0).getValue();
				}
			}
		} catch (Exception e) {
			log.fatal("Fatal error occurred while invoking postConstruct: " + e.getMessage(), e);
			throw new RuntimeException(e);
		}
	}

	private void fillListOfAvailableDefinitions(List<BuildDefinition> registeredBuildDefinitions) {
		availableDefinitions = new ArrayList<SelectItem>();
		for (BuildDefinition buildDefinition : registeredBuildDefinitions) {
			SelectItem selectItem = new SelectItem(buildDefinition, buildDefinition.getName());
			availableDefinitions.add(selectItem);
		}
	}

	public void prepareForNew() {
		editMode = true;
		chosenDefinition = new BuildDefinition();
	}

	public void prepareForEdit() {
		editModeOn();
	}

	public void choose() {
		editModeOff();
	}

	public void cancel() {
		editModeOff();
	}

	public void delete() {
		buildDefinitionService.delete(chosenDefinition);
		initBuildDefinitions();
		editModeOff();
	}

	public void saveChanges() {
		//save or update - no matter
		buildDefinitionService.update(chosenDefinition);
		initBuildDefinitions();
		BuildCityJobDetail jobDetail = new BuildCityJobDetail(chosenDefinition.getName()).withCronTrigger(chosenDefinition.getCronExpr());
		scheduler.save(jobDetail);
		//Fire initial build to have at least one activity in dashboard.
		scheduler.fireNow(jobDetail.getName());
		editModeOff();
	}

	private void editModeOff() {
		editMode = false;
	}

	private void editModeOn() {
		editMode = true;
	}

	public List<SelectItem> getAvailableDefinitions() {
		return availableDefinitions;
	}

	public void setBuildDefinitionService(BuildDefinitionService buildDefinitionService) {
		this.buildDefinitionService = buildDefinitionService;
	}

	public BuildDefinition getChosenDefinition() {
		return chosenDefinition;
	}

	public void setChosenDefinition(BuildDefinition chosenDefinition) {
		this.chosenDefinition = chosenDefinition;
	}

	public boolean isEditMode() {
		return editMode;
	}

	public void setScheduler(BuildCityScheduler scheduler) {
		this.scheduler = scheduler;
	}
}
